package com.gitee.fanx.retty.web;

import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.codec.http.QueryStringDecoder;

/**
 * @author fanhang
 */
public class Request {

	private FullHttpRequest request;

	private QueryStringDecoder queryStringDecoder;

	private Map<String, Object> attributes = null;

	public Request(FullHttpRequest request) {
		this.request = request;
		this.queryStringDecoder = new QueryStringDecoder(request.uri());
		this.attributes = new HashMap<>();
	}

	public HttpMethod method() {
		return request.method();
	}

	public HttpVersion protocolVersion() {
		return request.protocolVersion();
	}

	public String path() {
		return queryStringDecoder.path();
	}

	public String url() {
		return request.uri();
	}

	public String body() {
		return request.content().toString(StandardCharsets.UTF_8);
	}

	public List<String> queryParams(String queryParam) {
		return queryStringDecoder.parameters().get(queryParam);
	}

	public List<String> queryParamsSafe(final String queryParam) {
		return this.queryParams(queryParam).stream().map(i -> Base64Utils.encode(i)).collect(Collectors.toList());
	}

	public String queryParamFirst(String queryParam) {
		List<String> values = queryParams(queryParam);
		return values == null || values.isEmpty() ? "" : values.get(0);
	}

	public String header(String name) {
		return request.headers().get(name);
	}

	public Set<String> queryParams() {
		return queryStringDecoder.parameters().keySet();
	}

	public String queryString() {
		return this.queryStringDecoder.rawQuery();
	}

	public void attribute(String attribute, Object value) {
		this.attributes.put(attribute, value);
	}

	public Object attribute(String attribute) {
		return this.attributes.get(attribute);
	}

	public Set<String> attributes() {
		return this.attributes.keySet();
	}

	public FullHttpRequest raw() {
		return request;
	}

}
